package com.hu.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.hu.mapper.MusicMapping;
 import com.hu.utils.RestfulUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通用文件控制器
 */
@Controller
@RequestMapping("file")
@Slf4j
public class FileResourceController {

    String profile ="C:\\ruan_upload\\";

    @Autowired
    MusicMapping musicMapping;


    /**
     * 上传
     *
     * @param files
     * @return
     */
    @RequestMapping(value = "upload", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String upload(@RequestParam("files") List<MultipartFile> files) {
         List result = new ArrayList();
        List<String> failFileName = new ArrayList<>();
        for (int i = 0; i < files.size(); i++) {
            MultipartFile file = files.get(i);
            if (file.isEmpty()) {
                return RestfulUtil.toRestful(null,"没有选择文件!",500);
            }
            Digester md5Util = new Digester(DigestAlgorithm.MD5);
            String fileMd5 = null;
            try {
                fileMd5 = md5Util.digestHex(file.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }

                String fileName = file.getOriginalFilename();
                fileName = fileName.replace("." + FileUtil.getSuffix(fileName), "_" + UUID.randomUUID() + "." + FileUtil.getSuffix(fileName));
                File filePath = new File(profile);
                if (!filePath.exists()) {
                    filePath.mkdirs();
                }
                File dest = new File(filePath.getPath() + File.separator + fileName);
                try {
                    file.transferTo(dest);
                    Map<String,Object> map = new HashMap<>();
                    map.put("fileName",fileName);
                    map.put("url","/file/download/path/" + fileName);
                    result.add(map);
                } catch (IOException e) {
                    failFileName.add(fileName);
                    log.error("文件" + fileName + "上传失败！");
                }
            }

        if (failFileName.size() > 0) {
            return  RestfulUtil.toRestful(result,result.size() + "个文件上传成功," + failFileName.size() + "个文件上传失败！",200);

        } else {
            return RestfulUtil.toRestful(result,result.size() + "个文件上传成功",200);
        }
    }

    /**
     * 根据资源相对路径下载
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("download/path/**")
    public String download(HttpServletRequest request, HttpServletResponse response) {
        String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        String fileName = new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
        File file = new File(profile +  fileName);
        if (file.exists()) {
            response.setContentType(new MimetypesFileTypeMap().getContentType(file));
            response.setCharacterEncoding("UTF-8");
            try {
                response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(file.getName(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            OutputStream os = null;
            try {
                os = response.getOutputStream();
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer);
                    i = bis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                bis.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据歌曲ID下载
     *
     * @param id
     * @param response
     * @return
     */
    @GetMapping("download/id/{id}")
    public String downloadById(@PathVariable("id") Integer id, HttpServletResponse response) {
        File file = new File(musicMapping.queryById(id).getMusicUrl());
        if (file.exists()) {
            response.setContentType(new MimetypesFileTypeMap().getContentType(file));
            response.setCharacterEncoding("UTF-8");
            try {
                response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(file.getName(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            OutputStream os = null;
            try {
                os = response.getOutputStream();
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer);
                    i = bis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                bis.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
